'use strict';

const axios = require('axios');
const urlJoin = require('url-join');
const semver = require('semver');
const log = require('@yuyd-cli-dev/log');

function getNpmInfo(npmName, registry) {
  if (!npmName) {
    return null;
  }
  const registryUrl = registry || getDefultRegistry();
  const npmInfoUrl = urlJoin(registryUrl, npmName);
  return axios
    .get(npmInfoUrl)
    .then((response) => {
      if (response.status === 200) {
        return response.data;
      } else {
        return null;
      }
    })
    .catch((err) => {
      return Promise.reject(err);
    });
}

async function getNpmVersions(npmName, registry) {
  const data = await getNpmInfo(npmName, registry);
  if (data) {
    return await Object.keys(data.versions);
  } else {
    return [];
  }
}
// 过滤版本号，按着倒序排列版本号
function getNpmSemverVersions(baseVersion, versions) {
  return versions
    .filter((version) => semver.satisfies(version, `^${baseVersion}`))
    .sort((a, b) => {
      return semver.gt(b, a);
    });
}

async function getNpmSemverVersion(baseVersion, npmName, registry) {
  const versions = await getNpmVersions(npmName, registry);
  const newVersions = getNpmSemverVersions(baseVersion, versions);
  if (newVersions && newVersions.length > 0) {
    return newVersions[0];
  }
}

function getDefultRegistry(isOriginal = false) {
  return 'https://registry.npmjs.org';
  // ? 'https://registry.npmjs.org'
  // : 'https://registry.npm.taobao.org';
}

async function getNpmLatestVersion(npmName, registry) {
  const versions = await getNpmVersions(npmName, registry);

  if (versions) {
    // sort函数 如果指明了 compareFunction ，那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素：

    // 如果 compareFunction(a, b) 小于 0 ，那么 a 会被排列到 b 之前；
    // 如果 compareFunction(a, b) 等于 0 ， a 和 b 的相对位置不变。备注： ECMAScript 标准并不保证这一行为，而且也不是所有浏览器都会遵守（例如 Mozilla 在 2003 年之前的版本）；
    // 如果 compareFunction(a, b) 大于 0 ， b 会被排列到 a 之前。
    // compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果，否则排序的结果将是不确定的。
    log.verbose(
      'versions.sort((a, b) => (semver.gt(b, a) ? 1 : -1)):',
      versions.sort((a, b) => (semver.gt(b, a) ? 1 : -1))
    );
    return versions.sort((a, b) => (semver.gt(b, a) ? 1 : -1))[0];
  } else {
    return null;
  }
}
module.exports = {
  getNpmInfo,
  getNpmVersions,
  getNpmSemverVersion,
  getDefultRegistry,
  getNpmLatestVersion
};
